package com.lxy.controller.User;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lxy.common.BaseContext;
import com.lxy.common.R;
import com.lxy.constant.CodeConstant;
import com.lxy.constant.JwtClaimsConstant;
import com.lxy.dto.*;
import com.lxy.entity.*;
import com.lxy.properties.JwtProperties;
import com.lxy.service.*;
import com.lxy.utils.JwtUtil;
import com.lxy.vo.SearchByMapVO;
import com.lxy.vo.UserLoginVO;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private BuyOrderService buyOrderService;
    @Autowired
    private HistoryOrderService historyOrderService;
    @Autowired
    private SendOrderService sendOrderService;
    @Autowired
    private HistorySendOrderService historySendOrderService;
    @Autowired
    private AddressBookService addressBookService;
    @Autowired
    private RiderService riderService;
    @Autowired
    private RiderPlaceService riderPlaceService;
    @Autowired
    private MailSender mailSender;
    @Autowired
    private RiderAccountService riderAccountService;

    private String ak="wUO6QkgZ21Db6nOR1QdvbAzphr9omiSV";
    public static final String title="飞鸟跑腿";


    /**
     * 获取配送费
     */
    @ApiOperation("获取配送费")
    @PostMapping("/accountAmount")
    public R<BigDecimal> accountAmount(@RequestBody LogAndLatDTO logAndLatDTO){
        String url = "https://api.map.baidu.com/directionlite/v1/riding?origin={},{}&destination={},{}&ak={}";
        url = StrUtil.format(url, logAndLatDTO.getPurchaseLatitude()
                , logAndLatDTO.getPurchaseLongitude()
                , logAndLatDTO.getDeliveryLatitude()
                , logAndLatDTO.getDeliveryLongitude()
                , ak);
        String body = HttpRequest.get(url).execute().body();
//        RoutePlanningDTO routePlanningDTO = JSON.parseObject(body, RoutePlanningDTO.class);
//        Integer distance = routePlanningDTO.getResult().getRoutes().getDistance();
        //TODO 方法有点笨，后期改进
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONObject result = jsonObject.getJSONObject("result");
        JSONArray routes = result.getJSONArray("routes");
        JSONObject jsonObject1 = routes.getJSONObject(0);
        Integer distance = jsonObject1.getInteger("distance");
        distance=distance/1000;
        if(distance<=3){
            return R.success(BigDecimal.valueOf(13));
        }else{
            int amount = (distance - 3)*2+13;
            return R.success(BigDecimal.valueOf(amount));
        }
    }




    /**
     * 发送email
     */
    public void sendEmail(String email,String title,String text){
        //给用户发消息
        SimpleMailMessage mailMessage = new SimpleMailMessage(); //创建一个邮件信息
        System.out.println("当前时间" + new Date());
        mailMessage.setSubject(title);//邮件的主题
        mailMessage.setText(text);//邮件的内容
        mailMessage.setTo(email);//接收者的邮箱
        mailMessage.setFrom("3319725459@qq.com");//发送者的邮箱
        mailSender.send(mailMessage);//发送邮件
    }




    /**
     * 用户登录
     */
    @ApiOperation("用户登录")
    @PostMapping("/login")
    public R<UserLoginVO> login(@RequestBody LoginDTO loginDTO){
        //判断账户是否存在
        String account = loginDTO.getAccount();
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getAccount,account);
        User user = userService.getOne(lambdaQueryWrapper);
        if(user==null){
            return R.error("账户不存在，请先注册");
        }
        //账户存在，判断密码是否正确
        String correctPassword = user.getPassword();
        String password = DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes());
        if(!Objects.equals(password, correctPassword)){
            return R.error("账号或密码错误，请重试");
        }
        //判断账户是否被禁用
        Integer banded = user.getBanded();
        if(banded==0){
            return R.error("账户被禁用，如有疑惑请联系xxxxx");
        }
        //登录成功，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USERS_ID, user.getId());
        String token = JwtUtil.createJWT(
                jwtProperties.getUsersSecretKey(),
                jwtProperties.getUsersTtl(),
                claims);
        UserLoginVO userLoginVO=new UserLoginVO();
        userLoginVO.setToken(token);
        userLoginVO.setUser(user);
        return R.success(userLoginVO);
    }

    /**
     * 用户注册
     */
    @ApiOperation("用户注册")
    @PostMapping("/registration")
    public R registration(@RequestBody RegistrationDTO registrationDTO){
        //判断账号是否重复
        String account = registrationDTO.getAccount();
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getAccount,account);
        User getByAccount = userService.getOne(lambdaQueryWrapper);
        if(getByAccount!=null){
            return R.error("账号名重复");
        }
        //判断电话号码是否重复
        String phone = registrationDTO.getPhone();
        lambdaQueryWrapper.clear();
        lambdaQueryWrapper.eq(User::getPhone,phone);
        User getByPhone = userService.getOne(lambdaQueryWrapper);
        if(getByPhone!=null){
            return R.error("电话号码重复，请更换电话号码");
        }
        //判断邮箱是否重复
        String email = registrationDTO.getEmail();
        lambdaQueryWrapper.clear();
        lambdaQueryWrapper.eq(User::getEmail,email);
        User getByEmail = userService.getOne(lambdaQueryWrapper);
        if(getByEmail!=null){
            //邮箱重复
            return R.error("邮箱已注册，请勿重复注册");
        }
        //判断redis中存储的验证码和用户输入的验证码是否相同
        ValueOperations valueOperations=redisTemplate.opsForValue();
        Integer rCode = (Integer)valueOperations.get(email+ CodeConstant.USER_REGISTRATION);
        if(!Objects.equals(rCode, registrationDTO.getCode())){
            //验证码错误
            return R.error("验证码错误");
        }
        //验证成功后，删除redis缓存
        redisTemplate.delete(CodeConstant.USER_REGISTRATION);
        //创建User用户
        User user=new User();
        BeanUtils.copyProperties(registrationDTO,user);
        String password = DigestUtils.md5DigestAsHex(registrationDTO.getPassword().getBytes());
        user.setPassword(password);
        user.setCreateTime(LocalDateTime.now());
        user.setBanded(1);
        user.setIsVip(0);
        //存储用户
        userService.save(user);
        //发送信息
        String text="感谢您对本软件的支持：“"+user.getName()+"” 您的用户申请已通过";
        sendEmail(user.getEmail(),title,text);
        return R.success("注册成功");
    }

    /**
     * 帮我买
     */
    @ApiOperation("帮我买")
    @PostMapping("/byForMe")
    public R<String> byForMe(@RequestBody BuyOrder buyOrder){
        Long userId = BaseContext.getCurrentId();
        buyOrder.setUserId(userId);
        buyOrder.setStatus(0);
        buyOrder.setCreateTime(LocalDateTime.now());
        buyOrder.setVersion(1);
        buyOrderService.save(buyOrder);
        return R.success("已下单，正在等待骑手接单");
    }

    /**
     * 查看正在进行的订单 TODO 还有快递订单
     */
    @ApiOperation("查看正在进行的订单")
    @GetMapping("/showOrders")
    public R<AllDoingOrder> showOrders(){
        Long userId = BaseContext.getCurrentId();
        LambdaQueryWrapper<BuyOrder> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BuyOrder::getUserId,userId);
        List<BuyOrder> buyOrders = buyOrderService.list(lambdaQueryWrapper);
        LambdaQueryWrapper<SendOrder> lambdaQueryWrapper1=new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.eq(SendOrder::getUserId,userId);
        List<SendOrder> sendOrders = sendOrderService.list(lambdaQueryWrapper1);
        AllDoingOrder allDoingOrder=new AllDoingOrder();
        allDoingOrder.setBuyOrders(buyOrders);
        allDoingOrder.setSendOrders(sendOrders);
        return R.success(allDoingOrder);
    }

    /**
     * 查看历史订单 TODO 还有快递订单
     */
    @ApiOperation("查看历史订单")
    @GetMapping("/showHistoryOrders")
    public R<AllHistoryOrder> showHistoryOrders(){
        Long userId = BaseContext.getCurrentId();
        LambdaQueryWrapper<HistoryOrder> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(HistoryOrder::getUserId,userId);
        List<HistoryOrder> historyOrders = historyOrderService.list(lambdaQueryWrapper);
        LambdaQueryWrapper<HistorySendOrder> historySendOrderLambdaQueryWrapper=new LambdaQueryWrapper<>();
        historySendOrderLambdaQueryWrapper.eq(HistorySendOrder::getUserId,userId);
        List<HistorySendOrder> historySendOrders = historySendOrderService.list(historySendOrderLambdaQueryWrapper);
        AllHistoryOrder allHistoryOrder=new AllHistoryOrder();
        allHistoryOrder.setHistoryOrders(historyOrders);
        allHistoryOrder.setHistorySendOrders(historySendOrders);
        return R.success(allHistoryOrder);
    }


    /**
     * 帮我送、帮我取
     */
    @ApiOperation("帮我送、帮我取")
    @PostMapping("/sendOrTake")
    public R<String> sendOrTake(@RequestBody SendOrder sendOrder){
        Long userId = BaseContext.getCurrentId();
        sendOrder.setUserId(userId);
        sendOrder.setStatus(0);
        sendOrder.setCreateTime(LocalDateTime.now());
        sendOrderService.save(sendOrder);
        return R.success("订单已提交，正在等待骑手接单");
    }




    /**
     * 根据城市和字段查找地点
     */
    @ApiOperation("根据城市和字段查找地点")
    @GetMapping("/findPlace")
    public R findPlace(String city,String placeName) throws Exception {
        try{
            String url="https://api.map.baidu.com/place/v2/suggestion?query={}&region={}&city_limit=true&output=json&ak={}";
            url= StrUtil.format(url,placeName,city,ak);
            String body = HttpRequest.get(url).execute().body();
            ResultDTO resultDTO = JSON.parseObject(body, ResultDTO.class);
            //对结果进行处理,返回给前端
            List<SearchByMapVO> list=new ArrayList<>();
            resultDTO.getResult().stream().forEach(item->{
                SearchByMapVO searchByMapVO=new SearchByMapVO();
                searchByMapVO.setName(item.getName());
                searchByMapVO.setAddress(item.getAddress());
                Double lng= Double.valueOf(item.getLocation().getLng());
                Double lat=Double.valueOf(item.getLocation().getLat());
                searchByMapVO.setLongitude(lng);
                searchByMapVO.setLatitude(lat);
                list.add(searchByMapVO);
                //判断是否有children
                List<ChildrenDTO> children = item.getChildren();
                if(children!=null){
                    SearchByMapVO searchByMapVO1=new SearchByMapVO();
                    children.stream().forEach(child->{
                        searchByMapVO1.setName(child.getName());
                        searchByMapVO1.setAddress(item.getAddress());
                        searchByMapVO1.setLongitude(lng);
                        searchByMapVO1.setLatitude(lat);
                        list.add(searchByMapVO1);
                    });
                }
            });
            return R.success(list);
        }catch (Exception e){
            throw new Exception("网络繁忙，请稍后再试");
        }
    }

    /**
     * 骑手快速注册（用户界面内）
     */
    @ApiOperation("骑手快速注册（用户界面内）")
    @PostMapping("/fastRegistration")
    public R<String> fastRegistration(@RequestBody RiderFastRegistrationDTO riderFastRegistrationDTO){
        //先查找是否已经注册成为骑手
        LambdaQueryWrapper<Rider> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Rider::getEmail,riderFastRegistrationDTO.getEmail());
        Rider rider = riderService.getOne(lambdaQueryWrapper);
        if(rider!=null){
            return R.error("已经注册成为骑手，请勿重复注册");
        }
        Long userId = BaseContext.getCurrentId();
        //根据userId查找对应user数据
        User user = userService.getById(userId);
        //判断验证码是否正确
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String key=user.getEmail()+ CodeConstant.RIDER_REGISTRATION;
        Integer Rcode =(Integer) valueOperations.get(key);
        if(!Rcode.equals(riderFastRegistrationDTO.getCode())){
            //验证码错误
            return R.error("验证码错误，请重试");
        }
        //验证码正确，删除缓存
        redisTemplate.delete(key);
        //创建rider数据，status设为0
        Rider newRider =new Rider();
        BeanUtils.copyProperties(user,newRider);
        newRider.setId(null);
        newRider.setCreateTime(LocalDateTime.now());
        newRider.setStatus(0);
        newRider.setIsOk(0);
        newRider.setIsSend(0);
        newRider.setMonthAppraise(BigDecimal.valueOf(4.0));
        riderService.save(newRider);
        //创造rider_place数据
        RiderPlace riderPlace=new RiderPlace();
        BeanUtils.copyProperties(riderFastRegistrationDTO,riderPlace);
        riderPlace.setRiderId(newRider.getId());
        riderPlaceService.save(riderPlace);
        //发送邮件到用户邮箱
        String text="感谢您对本软件的支持："+newRider.getName()+" 您的骑手申请已经提交，将在七个工作日内审核";
        sendEmail(newRider.getEmail(),"飞鸟跑腿APP",text);
        //创建riderAccount数据
        RiderAccount riderAccount=new RiderAccount();
        riderAccount.setRiderId(newRider.getId());
        riderAccount.setMoney(BigDecimal.valueOf(0));
        riderAccount.setOrderNumber(0L);
        riderAccountService.save(riderAccount);
        return R.success("提交成功,将在七个工作日内审核");
    }


    /**
     * 查看我的信息
     * @return
     */
    @ApiOperation("查看我的信息")
    @GetMapping("/myInformation")
    public R<User> myInformation(){
        Long userId = BaseContext.getCurrentId();
        User user = userService.getById(userId);
        return R.success(user);
    }

    /**
     * 修改个人信息
     * @param user
     * @return
     */
    @ApiOperation("修改个人信息")
    @PostMapping("/updateInformation")
    public R<String> updateInformation(@RequestBody User user){
        userService.updateById(user);
        return R.success("修改信息成功");
    }
























}
